package c2.cross.business.minecraft.core;

import c2.cross.business.base.CrossSubModule;
import c2.cross.business.minecraft.MinecraftModule;
import cate.game.pvp.minecraft.MinecraftInnerMsg;
import cate.game.pvp.minecraft.MinecraftMessagingModule.*;
import cate.game.res.MixRes;
import cate.game.role.RoleSnapshot;
import cate.game.role.pvp.minecraft.msg.MinecraftMineAreaFightResultResp;
import cate.game.role.pvp.minecraft.msg.MinecraftMineAreaLayerInfoResp;
import cate.game.role.pvp.minecraft.msg.MinecraftMineAreaOverviewResp;
import cate.game.role.pvp.minecraft.msg.MinecraftMineAreaPointDetailResp;
import cp.solution.rpc.RpcMsgHead;
import easy.java.dev.note.NoteClass;
import easy.java.practice.errorcode.EcResult;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ExecutionException;

@Slf4j
@NoteClass("灵能矿洞-消息接受模块")
public class MinecraftCrossReceiveModule extends CrossSubModule<MinecraftModule> {

    @Override
    public void initDependent() throws Exception {
        super.initDependent();
        useRpcRecv().onFireAndForgetTemplate(MinecraftInnerMsg.MC_GAME_CONNECT, Integer.class, this::onGameConnect);
        useRpcRecv().onFireAndForgetTemplate(MinecraftInnerMsg.MC_ROLE_ONLINE, RoleSnapshot.class, this::onRoleOnline);
        useRpcRecv().onFireAndForgetTemplate(MinecraftInnerMsg.MC_OVERVIEW, CrossOverviewParams.class, this::crossOverview);
        useRpcRecv().onFireAndForgetTemplate(MinecraftInnerMsg.MC_VIEW_LAYER, CrossViewLayerParams.class, this::crossViewLayer);
        useRpcRecv().onFireAndForgetTemplate(MinecraftInnerMsg.MC_VIEW_MY_POINTS, CrossViewMyPointsParams.class, this::crossViewMyPoints);
        useRpcRecv().onFireAndForgetTemplate(MinecraftInnerMsg.MC_VIEW_POINT_DETAIL, CrossViewPointDetailParams.class, this::crossViewPointDetail);
        useRpcRecv().onFireAndForgetTemplate(MinecraftInnerMsg.MC_TRY_FIGHT, CrossTryFightPointParams.class, this::crossTryFight);
        useRpcRecv().onFireAndForgetTemplate(MinecraftInnerMsg.MC_FIGHT_RESULT_REPORT, CrossFightResultReportParams.class, this::crossFightResultReport);
        useRpcRecv().onFireAndForgetTemplate(MinecraftInnerMsg.MC_GET_HANG_REWARD, CrossGetHangRewardParams.class, this::crossGetHangReward);
        useRpcRecv().onFireAndForgetTemplate(MinecraftInnerMsg.MC_PROTECT_POINT, CrossProtectPointParams.class, this::crossProtectPoint);
        useRpcRecv().onFireAndForgetTemplate(MinecraftInnerMsg.MC_GIVE_UP_POINT, CrossGiveUpPointParams.class, this::crossGiveUpPoint);

        useRpcRecv().onRequestResponseTemplate(MinecraftInnerMsg.MC_MERGE_SETTLE, Integer.class, this::minecraftMergeSettle);
        useRpcRecv().onFireAndForgetTemplate(MinecraftInnerMsg.MC_GM_CMD, CrossGMCmd.class, this::crossGMCmd);
    }

    /**
     * 安全执行任务
     */
    public void safeTaskSubmit(Runnable task) {
        parent.getExecutor().submit(() -> {
            try {
                task.run();
            } catch (Exception e) {
                log.error("", e);
            }
        });
    }

    /**
     * 游戏服连接
     *
     * @param head  头信息
     * @param srvId 服务器ID
     */
    public void onGameConnect(RpcMsgHead head, int srvId) {
        safeTaskSubmit(() -> parent.onGameConnect(srvId));
    }

    /**
     * 玩家上线
     *
     * @param head         头信息
     * @param roleSnapshot 玩家快照
     */
    public void onRoleOnline(RpcMsgHead head, RoleSnapshot roleSnapshot) {
        safeTaskSubmit(() -> {
            // 同步占用信息
            parent.getModule().syncRoleUsedInfo(parent.getCrossRoleUsedInfo(roleSnapshot.uid,
                    roleSnapshot.base.srvId));
            // 同步自己的点位简要信息
            parent.viewMyPoints(roleSnapshot.uid, roleSnapshot.base.srvId, false);
        });
    }

    /**
     * 查看概览
     *
     * @param head   头信息
     * @param params 参数
     */
    public void crossOverview(RpcMsgHead head, CrossOverviewParams params) {
        safeTaskSubmit(() -> {
            MinecraftMineAreaOverviewResp resp = parent.overview();
            parent.getModule().sendBackOverview(params.roleUid, params.srvId, resp);
        });
    }

    /**
     * 查看单层信息
     *
     * @param head   头信息
     * @param params 参数
     */
    public void crossViewLayer(RpcMsgHead head, CrossViewLayerParams params) {
        safeTaskSubmit(() -> {
            EcResult<MinecraftMineAreaLayerInfoResp> r = parent.viewLayer(params);
            parent.getModule().sendBackViewLayer(params.roleUid, params.srvId, r);
        });
    }

    /**
     * 查看我的矿点
     *
     * @param head   头信息
     * @param params 参数
     */
    public void crossViewMyPoints(RpcMsgHead head, CrossViewMyPointsParams params) {
        safeTaskSubmit(() -> parent.viewMyPoints(params.roleUid, params.srvId, params.detail));
    }

    /**
     * 查看矿点详情
     *
     * @param head   头信息
     * @param params 参数
     */
    public void crossViewPointDetail(RpcMsgHead head, CrossViewPointDetailParams params) {
        safeTaskSubmit(() -> {
            EcResult<MinecraftMineAreaPointDetailResp> r = parent.viewPointDetail(params.layer, params.tid);
            parent.getModule().sendBackViewPointDetail(params.roleUid, params.srvId, r);
        });
    }

    /**
     * 尝试战斗
     *
     * @param head   头信息
     * @param params 参数
     */
    public void crossTryFight(RpcMsgHead head, CrossTryFightPointParams params) {
        safeTaskSubmit(() -> {
            CrossTryFightPointBack back = parent.tryFightPointBack(params);
            parent.getModule().sendBackTryFight(back);
        });
    }

    /**
     * 战斗结果上报
     *
     * @param head   头信息
     * @param params 参数
     */
    public void crossFightResultReport(RpcMsgHead head, CrossFightResultReportParams params) {
        safeTaskSubmit(() -> {
            EcResult<MinecraftMineAreaFightResultResp> r = new EcResult<>();
            MixRes lostRes = new MixRes();
            byte fightType = parent.handleFightResultReport(params, lostRes, r);
            parent.getModule().sendBackFightResult(
                    params.roleSnapshot.uid,
                    params.roleSnapshot.base.srvId,
                    fightType,
                    lostRes,
                    parent.getRoleProtectTime(params.roleSnapshot.uid),
                    r);
            // 无论如何 处理完之后同步一下角色占用信息
            parent.getModule().syncRoleUsedInfo(parent.getCrossRoleUsedInfo(params.roleSnapshot.uid,
                    params.roleSnapshot.base.srvId));
        });
    }

    /**
     * 领取挂机奖励
     *
     * @param head   头信息
     * @param params 参数
     */
    public void crossGetHangReward(RpcMsgHead head, CrossGetHangRewardParams params) {
        safeTaskSubmit(() -> {
            EcResult<MixRes> r;
            if (params.layer == 0 && params.tid == 0) {
                r = parent.getAllHangReward(params.roleUid);
            } else {
                r = parent.getHangReward(params.roleUid, params.layer, params.tid);
            }
            parent.getModule().sendBackGetHangReward(params.roleUid, params.srvId, r);
        });
    }

    /**
     * 保护矿点
     *
     * @param head   头信息
     * @param params 参数
     */
    public void crossProtectPoint(RpcMsgHead head, CrossProtectPointParams params) {
        safeTaskSubmit(() -> {
            EcResult<Long> result = parent.protectPoint(params.roleUid);
            parent.getModule().sendBackProtectPoint(params.roleUid, params.srvId, result);
        });
    }

    /**
     * 放弃矿点
     *
     * @param head   头信息
     * @param params 参数
     */
    public void crossGiveUpPoint(RpcMsgHead head, CrossGiveUpPointParams params) {
        safeTaskSubmit(() -> {
            EcResult<MixRes> result = parent.giveUpPoint(params.roleUid, params.srvId, params.layer, params.tid);
            parent.getModule().sendBackGiveUpPoint(params.roleUid, params.srvId, params.layer, params.tid, result);
        });
    }

    /**
     * 合服处理
     *
     * @param head  头信息
     * @param srvId 服务器ID
     * @return 添加的结算邮件列表
     */
    public MinecraftMergeMails minecraftMergeSettle(RpcMsgHead head, int srvId) {
        try {
            return parent.getExecutor().submit(() -> {
                try {
                    return parent.mergeSettlePoint(srvId);
                } catch (Exception e) {
                    log.error("", e);
                    return null;
                }
            }).get();
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 矿洞GM命令
     *
     * @param head 头信息
     * @param cmd  GM命令
     */
    public void crossGMCmd(RpcMsgHead head, CrossGMCmd cmd) {
        safeTaskSubmit(() -> {
            switch (cmd.cmdType) {
                case HANG_REWARD_GENERATE: {
                    int layer = Integer.parseInt(cmd.params.get(0));
                    int tid = Integer.parseInt(cmd.params.get(1));
                    int minute = Integer.parseInt(cmd.params.get(2));
                    parent.GMHangReward(layer, tid, minute);
                }
                break;
                case FORCE_SETTLE: {
                    parent.onClose();
                }
                break;
                case CANCEL_LOCK: {
                    int layer = Integer.parseInt(cmd.params.get(0));
                    int tid = Integer.parseInt(cmd.params.get(1));
                    parent.GMCancelLock(layer, tid);
                }
                break;
                case SAVE: {
                    parent.GMSave();
                }
                break;
            }
        });
    }
}
